<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>渐进学习平台 - 知识训练馆</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        /* ===== 基础样式重置 ===== */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
        }

        /* ===== CSS 变量定义 ===== */
        :root {
            --primary-color: #3f51b5;
            --primary-light: #e8eaf6;
            --secondary-color: #ff4081;
            --accent-color: #00bcd4;
            --text-primary: #212121;
            --text-secondary: #757575;
            --text-light: #9e9e9e;
            --background-light: #f5f5f5;
            --white: #ffffff;
            --border-color: #e0e0e0;
            --success-color: #4caf50;
            --warning-color: #ff9800;
            --danger-color: #f44336;
            --shadow-light: 0 2px 10px rgba(0, 0, 0, 0.05);
            --shadow-medium: 0 5px 15px rgba(0, 0, 0, 0.08);
            --shadow-heavy: 0 10px 25px rgba(0, 0, 0, 0.12);
            --border-radius: 8px;
            --transition: all 0.3s ease;
        }

        body {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: var(--text-primary);
            line-height: 1.6;
            min-height: 100vh;
            padding: 20px;
        }

        /* ===== 导航栏样式 ===== */
        .navbar {
            background: var(--white);
            box-shadow: var(--shadow-light);
            padding: 15px 0;
            z-index: 100;
            border-radius: 12px;
            margin-bottom: 30px;
        }

        .navbar .container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 20px;
        }

        .nav-brand {
            display: flex;
            align-items: center;
            font-size: 24px;
            font-weight: 700;
            color: var(--primary-color);
        }

        .nav-brand i {
            margin-right: 10px;
            font-size: 26px;
        }

        .nav-buttons {
            display: flex;
            gap: 15px;
        }

        /* ===== 按钮样式 ===== */
        .btn {
            padding: 10px 20px;
            border-radius: var(--border-radius);
            text-decoration: none;
            font-weight: 600;
            transition: var(--transition);
            display: inline-flex;
            align-items: center;
            cursor: pointer;
            border: none;
            font-size: 14px;
        }

        .btn-outline {
            border: 2px solid var(--primary-color);
            color: var(--primary-color);
            background: transparent;
        }

        .btn-primary {
            background: var(--primary-color);
            color: var(--white);
            box-shadow: var(--shadow-light);
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: var(--shadow-medium);
        }

        .btn-outline:hover {
            background: var(--primary-color);
            color: var(--white);
        }

        /* ===== 主要内容区域 ===== */
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        .main-content {
            background: var(--white);
            border-radius: 12px;
            padding: 30px;
            box-shadow: var(--shadow-light);
            margin-bottom: 30px;
        }

        .page-header {
            text-align: center;
            margin-bottom: 40px;
            padding: 20px 0;
        }

        .page-title {
            font-size: 32px;
            color: var(--text-primary);
            margin-bottom: 15px;
            font-weight: 700;
        }

        .page-subtitle {
            font-size: 18px;
            color: var(--text-secondary);
            max-width: 700px;
            margin: 0 auto 30px;
            line-height: 1.6;
        }

        /* ===== 知识层级导航样式 ===== */
        .hierarchy-nav {
            display: flex;
            flex-direction: column;
            gap: 15px;
            margin-bottom: 30px;
        }

        .hierarchy-level {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            align-items: center;
        }

        .hierarchy-label {
            font-weight: 600;
            color: var(--text-secondary);
            min-width: 80px;
            font-size: 14px;
        }

        .hierarchy-links {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }

        .hierarchy-link {
            display: inline-block;
            padding: 10px 20px;
            border: 2px solid var(--border-color);
            border-radius: 25px;
            background: var(--white);
            text-decoration: none;
            color: var(--text-primary);
            transition: var(--transition);
            white-space: nowrap;
            font-weight: 500;
            font-size: 14px;
        }

        .hierarchy-link.active {
            border-color: var(--primary-color);
            background: var(--primary-color);
            color: var(--white);
            box-shadow: 0 4px 15px rgba(63, 81, 181, 0.3);
        }

        .hierarchy-link:hover {
            text-decoration: none;
            color: var(--text-primary);
            border-color: var(--primary-color);
        }

        .hierarchy-link.active:hover {
            color: var(--white);
        }

        /* ===== 筛选区域 ===== */
        .filter-container {
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            margin-bottom: 30px;
            align-items: center;
        }

        .filter-dropdown {
            padding: 12px 15px;
            border: 1px solid var(--border-color);
            border-radius: var(--border-radius);
            background: var(--white);
            font-size: 16px;
            cursor: pointer;
            min-width: 180px;
        }

        /* ===== 知识包网格布局 ===== */
        .package-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
            gap: 25px;
            margin-bottom: 40px;
        }

        .package-card {
            background: var(--white);
            border-radius: var(--border-radius);
            overflow: hidden;
            box-shadow: var(--shadow-light);
            border: 1px solid var(--border-color);
            transition: var(--transition);
            display: flex;
            flex-direction: column;
            height: fit-content; /* 关键：让高度自适应内容 */
            min-height: 280px; /* 最小高度保持一致性 */
        }

        .package-card.locked {
            border: 1px dashed var(--warning-color);
        }

        .package-card:hover {
            transform: translateY(-5px);
            box-shadow: var(--shadow-heavy);
        }

        /* 添加展开时的视觉反馈 */
        .package-card.expanding {
            box-shadow: var(--shadow-heavy);
            border-color: var(--primary-color);
        }

        .package-header {
            padding: 20px 20px 0;
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
        }

        .package-title {
            font-size: 20px;
            font-weight: 700;
            color: var(--text-primary);
            margin-bottom: 10px;
            line-height: 1.3;
            flex: 1;
            margin-right: 12px;
        }

        .package-header-meta {
            display: flex;
            flex-direction: column;
            align-items: flex-end;
            gap: 6px;
            min-width: 150px;
        }

        .estimated-label {
            font-size: 13px;
            color: var(--text-secondary);
            white-space: nowrap;
        }

        .package-badge {
            background: var(--primary-light);
            color: var(--primary-color);
            padding: 5px 10px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 600;
        }

        .package-content {
            padding: 0 20px 20px;
            flex-grow: 1;
            display: flex;
            flex-direction: column;
        }

        .package-meta {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
            font-size: 14px;
            color: var(--text-secondary);
        }

        .package-description {
            color: var(--text-secondary);
            line-height: 1.5;
            margin-bottom: 20px;
            flex-grow: 1;
        }

        .package-stats {
            display: flex;
            justify-content: space-between;
            background: var(--background-light);
            padding: 12px;
            border-radius: var(--border-radius);
            margin-bottom: 20px;
            font-size: 14px;
        }

        .package-footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .progress-container {
            flex-grow: 1;
        }

        .progress-bar {
            height: 6px;
            background: var(--border-color);
            border-radius: 3px;
            overflow: hidden;
            margin-bottom: 5px;
        }

        .progress-fill {
            height: 100%;
            background: var(--success-color);
            border-radius: 3px;
        }

        .progress-text {
            font-size: 12px;
            color: var(--text-light);
        }

        .expand-btn {
            padding: 10px 15px;
            background: transparent;
            border: 1px solid var(--primary-color);
            color: var(--primary-color);
            border-radius: var(--border-radius);
            cursor: pointer;
            font-weight: 600;
            transition: var(--transition);
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 14px;
        }

        .expand-btn:hover {
            background: var(--primary-color);
            color: var(--white);
        }

        /* ===== 知识点列表样式 ===== */
        .points-container {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            margin-top: 0;
            border-top: none;
        }

        .points-container.expanded {
            max-height: 800px; /* 设置足够大的最大高度 */
            border-top: 1px solid var(--border-color);
            margin-top: 20px;
        }

        /* 知识点内容添加内边距 */
        .points-content {
            padding: 20px 20px 10px;
        }

        .knowledge-point {
            background: var(--background-light);
            border-radius: var(--border-radius);
            padding: 15px;
            margin-bottom: 15px;
            border-left: 4px solid var(--primary-color);
            transition: var(--transition);
        }

        .knowledge-point:hover {
            background: var(--primary-light);
        }

        .point-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
        }

        .point-title {
            font-weight: 600;
            color: var(--text-primary);
            flex-grow: 1;
        }

        .point-meta {
            display: flex;
            gap: 15px;
            font-size: 12px;
            color: var(--text-secondary);
            margin-bottom: 8px;
        }

        .point-description {
            color: var(--text-secondary);
            font-size: 14px;
            line-height: 1.4;
        }

        /* ===== 难度徽章样式 ===== */
        .difficulty-badge {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 4px 16px;
            border-radius: 999px;
            font-size: 16px;
            font-weight: 700;
            min-width: 76px;
            text-transform: none;
        }

        .difficulty-beginner {
            background: rgba(76, 175, 80, 0.1);
            color: var(--success-color);
        }
        .difficulty-intermediate {
            background: rgba(255, 152, 0, 0.1);
            color: var(--warning-color);
        }
        .difficulty-advanced {
            background: rgba(244, 67, 54, 0.1);
            color: var(--danger-color);
        }

        .status-pill {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 4px 12px;
            border-radius: 999px;
            font-size: 13px;
            font-weight: 600;
            background: rgba(15, 23, 42, 0.05);
            color: var(--text-secondary);
        }

        .status-pill.status-success {
            background: rgba(16, 185, 129, 0.15);
            color: #047857;
        }

        .status-pill.status-warning {
            background: rgba(245, 158, 11, 0.15);
            color: #92400e;
        }

        .status-pill.status-warning {
            background: rgba(245, 158, 11, 0.15);
            color: #92400e;
        }

        /* ===== 开始学习按钮 ===== */
        .start-point-btn {
            width: 100%;
            padding: 10px;
            background: var(--primary-color);
            color: var(--white);
            border: none;
            border-radius: var(--border-radius);
            cursor: pointer;
            font-weight: 600;
            margin-top: 10px;
            transition: var(--transition);
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        .start-point-btn:hover {
            background: #303f9f;
            transform: translateY(-2px);
            box-shadow: var(--shadow-medium);
        }

        .start-point-btn.locked {
            background: #d1d5db;
            color: #6b7280;
            cursor: not-allowed;
        }

        .lock-hint {
            font-size: 13px;
            color: var(--warning-color);
            text-align: right;
            margin-top: 6px;
        }

        .knowledge-point.locked {
            border: 1px dashed var(--warning-color);
            background: var(--background-light);
        }

        /* ===== 优化加载状态 ===== */
        .loading-text {
            text-align: center;
            padding: 30px 20px;
            color: var(--text-light);
            font-size: 14px;
        }

        .loading-text i {
            margin-right: 8px;
        }

        /* ===== 分页样式 ===== */
        .pagination-container {
            margin: 40px 0 20px;
            text-align: center;
        }

        .page-info {
            margin-bottom: 15px;
            color: var(--text-secondary);
            font-size: 14px;
        }

        .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 5px;
            flex-wrap: wrap;
        }

        .page-link {
            padding: 10px 15px;
            border: 1px solid var(--border-color);
            border-radius: var(--border-radius);
            text-decoration: none;
            color: var(--text-primary);
            transition: var(--transition);
            font-size: 14px;
            min-width: 40px;
            text-align: center;
            display: inline-block;
        }

        .page-link:hover {
            background: var(--primary-color);
            color: var(--white);
            border-color: var(--primary-color);
        }

        .page-link.active {
            background: var(--primary-color);
            color: var(--white);
            border-color: var(--primary-color);
        }

        .page-link.disabled {
            color: var(--text-light);
            cursor: not-allowed;
            background: var(--background-light);
        }

        .page-ellipsis {
            padding: 10px 5px;
            color: var(--text-light);
        }

        .page-jump {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
            margin-top: 15px;
            flex-wrap: wrap;
        }

        .page-input {
            width: 60px;
            padding: 8px 10px;
            border: 1px solid var(--border-color);
            border-radius: var(--border-radius);
            text-align: center;
        }

        .jump-btn {
            padding: 8px 15px;
            background: var(--primary-color);
            color: var(--white);
            border: none;
            border-radius: var(--border-radius);
            cursor: pointer;
            font-size: 14px;
            transition: var(--transition);
        }

        .jump-btn:hover {
            background: #303f9f;
        }

        /* ===== 页脚样式 ===== */
        footer {
            text-align: center;
            color: var(--white);
            padding: 30px 0;
            margin-top: 40px;
            border-top: 1px solid rgba(255, 255, 255, 0.2);
        }

        footer p {
            margin-bottom: 15px;
            opacity: 0.9;
        }

        /* ===== 响应式设计 ===== */
        @media (max-width: 768px) {
            .nav-buttons {
                flex-direction: column;
                width: 100%;
                gap: 10px;
            }

            .navbar .container {
                flex-direction: column;
                gap: 15px;
            }

            .package-grid {
                grid-template-columns: 1fr;
            }

            .filter-container {
                flex-direction: column;
                align-items: stretch;
            }

            .hierarchy-level {
                flex-direction: column;
                align-items: flex-start;
            }

            .hierarchy-links {
                width: 100%;
                justify-content: flex-start;
            }

            .pagination {
                gap: 3px;
            }

            .page-link {
                padding: 8px 12px;
                font-size: 12px;
                min-width: 35px;
            }
        }

        @media (max-width: 480px) {
            .main-content {
                padding: 20px;
            }

            .package-card {
                padding: 15px;
            }

            .page-title {
                font-size: 28px;
            }
        }
    </style>
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar">
    <div class="container">
        <div class="nav-brand">
            <i class="fas fa-graduation-cap"></i> 渐进学习平台
        </div>
        <div class="nav-buttons">
            <!-- 从session中获取用户名 -->
            <span style="margin-right: 15px; color: var(--primary-color);">
                欢迎，<span id="username" th:text="${user?.username ?: '学习者'}">学习者</span>
            </span>
            <a href="/" class="btn btn-outline">返回首页</a>
            <a href="#" class="btn btn-outline">退出</a>
        </div>
    </div>
</nav>

<!-- 主要内容区域 -->
<div class="container">
    <div class="main-content">
        <!-- 页面标题区域 -->
        <div class="page-header">
            <h1 class="page-title">Java知识训练馆</h1>
            <p class="page-subtitle">选择知识分类、板块和知识包，像健身一样逐步提升编程能力！从基础到进阶，系统化学习Java技术栈。</p>
        </div>

        <!-- 四层级导航区域 -->
        <div class="hierarchy-nav">
            <!-- 知识分类层级 -->
            <div class="hierarchy-level">
                <div class="hierarchy-label">知识分类:</div>
                <div class="hierarchy-links">
                    <!-- 全部分类链接 -->
                    <a th:href="@{/knowledge/gym}"
                       th:class="${currentClassId == null} ? 'hierarchy-link active' : 'hierarchy-link'">全部分类</a>
                    <!-- 动态生成分类链接 -->
                    <a th:each="knowledgeClass : ${knowledgeClasses}"
                       th:href="@{/knowledge/gym(classId=${knowledgeClass.id})}"
                       th:text="${knowledgeClass.name}"
                       th:class="${currentClassId == knowledgeClass.id} ? 'hierarchy-link active' : 'hierarchy-link'"></a>
                </div>
            </div>

            <!-- 知识板块层级 -->
            <div class="hierarchy-level">
                <div class="hierarchy-label">知识板块:</div>
                <div class="hierarchy-links">
                    <!-- 全部板块链接 -->
                    <a th:href="@{/knowledge/gym(classId=${currentClassId})}"
                       th:class="${currentModuleId == null} ? 'hierarchy-link active' : 'hierarchy-link'">全部板块</a>
                    <!-- 动态生成板块链接 -->
                    <a th:each="module : ${modules}"
                       th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${module.id})}"
                       th:text="${module.name}"
                       th:class="${currentModuleId == module.id} ? 'hierarchy-link active' : 'hierarchy-link'"></a>
                </div>
            </div>

            <!-- 知识包层级 -->
            <div class="hierarchy-level">
                <div class="hierarchy-label">知识包:</div>
                <div class="hierarchy-links">
                    <!-- 全部知识包链接 -->
                    <a th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId})}"
                       th:class="${currentPackageId == null} ? 'hierarchy-link active' : 'hierarchy-link'">全部知识包</a>
                    <!-- 动态生成知识包链接 -->
                    <a th:each="pkg : ${knowledgePackages}"
                       th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId}, packageId=${pkg.id})}"
                       th:text="${pkg.name}"
                       th:class="${currentPackageId == pkg.id} ? 'hierarchy-link active' : 'hierarchy-link'"></a>
                </div>
            </div>
        </div>

        <!-- 筛选区域 -->
        <div class="filter-container">
            <select class="filter-dropdown" id="difficultyFilter">
                <option>全部难度</option>
                <option>初级</option>
                <option>中级</option>
                <option>高级</option>
            </select>
            <button class="btn btn-primary" onclick="applyFilters()">
                <i class="fas fa-filter"></i> 筛选
            </button>
        </div>

        <!-- 知识包网格容器 -->
        <div class="package-grid" id="packageContainer">
            <!-- 使用Thymeleaf循环渲染知识包 -->
            <div th:each="pkg,iterStat : ${knowledgePackages}"
                 th:class="'package-card' + (${pkg.locked} ? ' locked' : '')"
                 th:data-locked="${pkg.locked}"
                 th:data-completed="${pkg.completed}">
                <div class="package-header">
                    <div>
                        <h3 class="package-title" th:text="${pkg.name}">知识包名称</h3>
                        <div class="package-badge" th:text="${pkg.moduleName}">模块名称</div>
                    </div>
                    <div class="package-header-meta">
                        <span class="estimated-label">预计用时 <span th:text="${pkg.totalDuration ?: 0}">0</span> 分钟</span>
                        <span class="status-pill"
                              th:attr="data-default=${pkg.statusLabel} ?: '未开始'"
                              th:text="${pkg.locked} ? '待解锁' : (${pkg.statusLabel} ?: '未开始')"
                              th:classappend="${pkg.locked} ? ' status-warning' : (${pkg.completed} ? ' status-success' : '')">
                            未开始
                        </span>
                    </div>
                </div>
                <div class="package-content">
                    <!-- 知识包元信息 - 修复字段名匹配 -->
                    <div class="package-meta">
                        <span><i class="far fa-clock"></i> 累计投入 <span th:text="${pkg.actualDurationText ?: '0分钟'}">0分钟</span></span>
                        <span><i class="fas fa-star"></i> <span th:text="${pkg.totalExperience ?: 0}">0</span> 经验</span>
                        <span><i class="fas fa-book"></i> <span th:text="${pkg.pointCount ?: 0}">0</span> 个知识点</span>
                    </div>
                    <p class="package-description" th:text="${pkg.description}">描述信息</p>
                    <!-- 难度统计 - 修复字段名匹配 -->
                    <div class="package-stats">
                        <span class="difficulty-beginner difficulty-badge">初级: <span th:text="${pkg.beginnerPoints}">0</span></span>
                        <span class="difficulty-intermediate difficulty-badge">中级: <span th:text="${pkg.intermediatePoints}">0</span></span>
                        <span class="difficulty-advanced difficulty-badge">高级: <span th:text="${pkg.advancedPoints}">0</span></span>
                    </div>
                    <div class="package-footer">
                        <!-- 学习进度 -->
                        <div class="progress-container">
                            <div class="progress-bar">
                                <div class="progress-fill" th:style="'width: ' + ${pkg.progress != null ? pkg.progress : 0} + '%'"></div>
                            </div>
                            <div class="progress-text">已学习 <span th:text="${pkg.progress != null ? pkg.progress : 0}">0</span>%</div>
                        </div>
                        <!-- 展开知识点按钮 -->
                        <div>
                            <button class="expand-btn" th:attr="data-package-id=${pkg.id}">
                                <span>展开知识点</span>
                                <i class="fas fa-chevron-down"></i>
                            </button>
                            <div th:if="${pkg.locked}" class="lock-hint" th:text="${pkg.unlockHint ?: '完成上一知识包后自动解锁'}"></div>
                        </div>
                    </div>
                </div>
                <!-- 知识点容器（默认隐藏，点击展开后显示） -->
                <div class="points-container" th:id="'points-' + ${pkg.id}">
                    <div class="points-content">
                        <div class="loading-text">
                            <i class="fas fa-spinner fa-spin"></i> 加载知识点中...
                        </div>
                    </div>
                </div>
            </div>

            <!-- 如果没有知识包时显示的空状态 -->
            <div th:if="${#lists.isEmpty(knowledgePackages)}" class="no-packages" style="grid-column: 1 / -1; text-align: center; padding: 40px;">
                <i class="fas fa-inbox" style="font-size: 48px; color: var(--text-light); margin-bottom: 20px;"></i>
                <h3 style="color: var(--text-secondary);">暂无知识包</h3>
                <p style="color: var(--text-light);">当前筛选条件下没有找到知识包</p>
            </div>
        </div>

        <!-- 分页导航 -->
        <div class="pagination-container" th:if="${totalPages > 1}">
            <div class="page-info">
                共 <span id="totalItems" th:text="${totalItems}">0</span> 个知识包，第 <span id="currentPage" th:text="${currentPage}">1</span> 页，共 <span id="totalPages" th:text="${totalPages}">0</span> 页
            </div>
            <div class="pagination" id="pagination">
                <!-- 上一页按钮 -->
                <a th:if="${currentPage > 1}"
                   th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId}, packageId=${currentPackageId}, page=${currentPage - 1}, size=${pageSize})}"
                   class="page-link">‹ 上一页</a>
                <a th:unless="${currentPage > 1}" class="page-link disabled">‹ 上一页</a>

                <!-- 修复后的分页逻辑 -->
                <!-- 第一页 -->
                <a th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId}, packageId=${currentPackageId}, page=1, size=${pageSize})}"
                   th:class="${1 == currentPage} ? 'page-link active' : 'page-link'"
                   th:text="1">1</a>

                <!-- 前导省略号：当当前页距离第一页超过2页时显示 -->
                <span th:if="${currentPage > 3}" class="page-ellipsis">...</span>

                <!-- 修复后的中间页码逻辑：安全处理边界情况 -->
                <th:block th:with="start=${T(java.lang.Math).max(2, currentPage - 1)},
                                 end=${T(java.lang.Math).min(totalPages - 1, currentPage + 1)}">
                    <a th:if="${start <= end}"
                       th:each="i : ${#numbers.sequence(start, end)}"
                       th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId}, packageId=${currentPackageId}, page=${i}, size=${pageSize})}"
                       th:class="${i == currentPage} ? 'page-link active' : 'page-link'"
                       th:text="${i}">2</a>
                </th:block>

                <!-- 后导省略号：当当前页距离最后一页超过2页时显示 -->
                <span th:if="${currentPage < totalPages - 2}" class="page-ellipsis">...</span>

                <!-- 最后一页（当总页数大于1时显示） -->
                <a th:if="${totalPages > 1}"
                   th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId}, packageId=${currentPackageId}, page=${totalPages}, size=${pageSize})}"
                   th:class="${totalPages == currentPage} ? 'page-link active' : 'page-link'"
                   th:text="${totalPages}">10</a>

                <!-- 下一页按钮 -->
                <a th:if="${currentPage < totalPages}"
                   th:href="@{/knowledge/gym(classId=${currentClassId}, moduleId=${currentModuleId}, packageId=${currentPackageId}, page=${currentPage + 1}, size=${pageSize})}"
                   class="page-link">下一页 ›</a>
                <a th:unless="${currentPage < totalPages}" class="page-link disabled">下一页 ›</a>
            </div>
            <!-- 快速跳转 -->
            <div class="page-jump">
                <span>跳转到</span>
                <input type="number" class="page-input" id="jumpPage" min="1" th:max="${totalPages}" placeholder="页码">
                <span>页</span>
                <button class="jump-btn" onclick="jumpToPage()">确定</button>
            </div>
        </div>
    </div>

    <!-- 页脚 -->
    <footer>
        <p>&copy; 2024 渐进学习平台 - 让学习像健身一样科学有效</p>
        <p>联系我们: support@knowledge-gym.com</p>
    </footer>
</div>

<script>
    /**
     * 页面加载完成后执行的初始化函数
     */
    document.addEventListener('DOMContentLoaded', function() {
        console.log('知识训练馆页面初始化完成');

        enforcePackageLocks();

        // 为快速跳转输入框添加回车键支持
        const jumpInput = document.getElementById('jumpPage');
        if (jumpInput) {
            jumpInput.addEventListener('keypress', function(event) {
                if (event.key === 'Enter') {
                    jumpToPage();
                }
            });
        }

        // 使用事件委托处理知识点展开按钮点击
        document.addEventListener('click', function(e) {
            if (e.target.closest('.expand-btn')) {
                const btn = e.target.closest('.expand-btn');
                const card = btn.closest('.package-card');
                if (card && card.dataset.locked === 'true') {
                    alert('请先完成上一知识包后解锁下一包~');
                    return;
                }
                const packageId = btn.getAttribute('data-package-id');
                togglePoints(packageId);
            }
        });
    });

    function enforcePackageLocks() {
        const cards = Array.from(document.querySelectorAll('.package-card'));
        if (!cards.length) return;
        let allowNext = true;
        cards.forEach((card, index) => {
            const completed = card.dataset.completed === 'true';
            const explicit = card.dataset.locked;
            let locked;
            if (explicit === 'true' || explicit === 'false') {
                locked = explicit === 'true';
            } else {
                locked = index !== 0 && !allowNext;
            }
            if (index === 0) locked = false;
            card.dataset.locked = locked ? 'true' : 'false';
            card.classList.toggle('locked', locked);

            const expandBtn = card.querySelector('.expand-btn');
            if (expandBtn) {
                expandBtn.disabled = locked;
                expandBtn.classList.toggle('locked', locked);
            }

            const statusPill = card.querySelector('.status-pill');
            if (statusPill) {
                const defaultLabel = statusPill.dataset.default || statusPill.textContent.trim() || '未开始';
                statusPill.textContent = locked ? '待解锁' : defaultLabel;
                statusPill.classList.toggle('status-warning', locked);
                if (!locked) {
                    statusPill.classList.toggle('status-success', completed);
                }
            }

            const lockHint = card.querySelector('.lock-hint');
            if (lockHint) {
                lockHint.style.display = locked ? 'block' : 'none';
            }

            if (!locked && !completed) {
                allowNext = false;
            } else if (!locked && completed) {
                allowNext = true;
            }
        });
    }

    function applySequentialPointLocks(points) {
        if (!Array.isArray(points)) return [];
        let allowNext = true;
        return points.map((point, index) => {
            const completed = !!(point.completed || (point.progress >= 100));
            let locked;
            if (typeof point.locked === 'boolean') {
                locked = point.locked;
            } else {
                locked = index !== 0 && !allowNext;
            }
            if (index === 0) locked = false;
            const normalized = {
                ...point,
                locked,
                completed,
                unlockHint: point.unlockHint || '完成上一知识点后自动解锁'
            };
            if (!locked && !completed) {
                allowNext = false;
            } else if (!locked && completed) {
                allowNext = true;
            }
            return normalized;
        });
    }

    function resolveStatusLabel(item) {
        if (item.locked) return '待解锁';
        if (item.statusLabel) return item.statusLabel;
        if (item.completed) return '已完成';
        if (item.started || (item.actualDurationSeconds && item.actualDurationSeconds > 0)) return '学习中';
        return '未开始';
    }

    function resolveStatusClass(label) {
        if (!label) return 'status-warning';
        if (label.includes('完成')) return 'status-success';
        if (label.includes('锁') || label.includes('待') || label.includes('学习')) return 'status-warning';
        return 'status-warning';
    }

    function formatDurationLabel(seconds) {
        const totalSeconds = Number(seconds) || 0;
        if (totalSeconds <= 0) return '0分钟';
        const minutes = Math.floor(totalSeconds / 60);
        if (minutes < 1) return `${totalSeconds}秒`;
        if (minutes < 60) return `${minutes}分钟`;
        const hours = (minutes / 60).toFixed(1);
        return `${hours}小时`;
    }

    /**
     * 展开/收起知识点函数 - 优化版本
     * @param {string} packageId - 知识包ID
     */
    function togglePoints(packageId) {
        const pointsContainer = document.getElementById('points-' + packageId);
        const expandBtn = event.currentTarget;
        const packageCard = pointsContainer.closest('.package-card');

        // 如果已经展开，直接收起
        if (pointsContainer.classList.contains('expanded')) {
            collapsePoints(pointsContainer, expandBtn, packageCard);
            return;
        }

        // 关闭所有其他展开的知识点容器
        closeAllOtherPoints(packageId);

        // 展开当前知识点
        expandPoints(pointsContainer, expandBtn, packageCard, packageId);
    }

    /**
     * 收起知识点
     * @param {HTMLElement} container - 知识点容器
     * @param {HTMLElement} button - 展开按钮
     * @param {HTMLElement} card - 知识包卡片
     */
    function collapsePoints(container, button, card) {
        // 设置当前高度
        container.style.maxHeight = container.scrollHeight + 'px';

        // 强制重绘
        container.getBoundingClientRect();

        // 开始收起动画
        container.style.maxHeight = '0px';
        button.innerHTML = '<span>展开知识点</span><i class="fas fa-chevron-down"></i>';
        card.classList.remove('expanding');

        // 动画结束后移除expanded类
        setTimeout(() => {
            container.classList.remove('expanded');
        }, 400);
    }

    /**
     * 展开知识点
     * @param {HTMLElement} container - 知识点容器
     * @param {HTMLElement} button - 展开按钮
     * @param {HTMLElement} card - 知识包卡片
     * @param {string} packageId - 知识包ID
     */
    function expandPoints(container, button, card, packageId) {
        // 添加展开类
        container.classList.add('expanded');
        card.classList.add('expanding');
        button.innerHTML = '<span>收起知识点</span><i class="fas fa-chevron-up"></i>';

        // 设置初始高度为0
        container.style.maxHeight = '0px';

        // 强制重绘
        container.getBoundingClientRect();

        // 显示加载状态
        const pointsContent = container.querySelector('.points-content');
        pointsContent.innerHTML = `
      <div class="loading-text">
        <i class="fas fa-spinner fa-spin"></i> 加载知识点中...
      </div>
    `;

        // 设置加载时的高度
        container.style.maxHeight = '120px';

        // 从后端加载知识点数据
        fetch('/knowledge/package/' + packageId + '/points')
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络响应不正常');
                }
                return response.json();
            })
            .then(points => {
                if (points && points.length > 0) {
                    pointsContent.innerHTML = renderKnowledgePoints(points);
                } else {
                    pointsContent.innerHTML = `
            <div class="no-points" style="text-align: center; padding: 40px 20px; color: var(--text-light);">
              <i class="fas fa-inbox" style="font-size: 32px; margin-bottom: 10px;"></i>
              <p>暂无知识点</p>
            </div>
          `;
                }

                // 数据加载完成后设置最终高度
                setTimeout(() => {
                    container.style.maxHeight = container.scrollHeight + 'px';
                }, 50);
            })
            .catch(error => {
                console.error('加载知识点失败:', error);
                pointsContent.innerHTML = `
          <div class="error-text" style="text-align: center; padding: 40px 20px; color: var(--danger-color);">
            <i class="fas fa-exclamation-triangle" style="margin-bottom: 10px;"></i>
            <p>加载失败，请重试</p>
            <button class="retry-btn" onclick="retryLoadPoints('${packageId}')"
                    style="margin-top: 10px; padding: 5px 15px; background: var(--danger-color); color: white; border: none; border-radius: 4px; cursor: pointer;">
              重试
            </button>
          </div>
        `;
                container.style.maxHeight = '150px';
            });
    }

    /**
     * 关闭所有其他展开的知识点
     * @param {string} currentPackageId - 当前知识包ID
     */
    function closeAllOtherPoints(currentPackageId) {
        document.querySelectorAll('.points-container.expanded').forEach(container => {
            const otherPackageId = container.id.split('-')[1];
            if (otherPackageId !== currentPackageId) {
                const btn = document.querySelector(`.expand-btn[data-package-id="${otherPackageId}"]`);
                const card = container.closest('.package-card');
                collapsePoints(container, btn, card);
            }
        });
    }

    /**
     * 重试加载知识点
     * @param {string} packageId - 知识包ID
     */
    function retryLoadPoints(packageId) {
        const btn = document.querySelector(`.expand-btn[data-package-id="${packageId}"]`);
        if (btn) {
            // 使用自定义事件对象模拟点击
            const event = { currentTarget: btn };
            togglePoints.call(event, packageId);
        }
    }

    /**
     * 渲染知识点列表
     * @param {Array} points - 知识点数组
     * @returns {string} HTML字符串
     */
    function renderKnowledgePoints(points) {
        const normalized = applySequentialPointLocks(points);
        return `
      <div class="knowledge-points-list">
        ${normalized.map(point => {
            const difficultyKey = point.difficultyLevel || point.difficulty;
            const difficultyClass = getDifficultyClass(difficultyKey);
            const difficultyText = getDifficultyText(difficultyKey);
            const statusLabel = resolveStatusLabel(point);
            const statusClass = resolveStatusClass(statusLabel);
            const locked = !!point.locked;
            const buttonLabel = locked ? '待解锁' : '开始学习';
            const buttonClass = locked ? 'start-point-btn locked' : 'start-point-btn';
            const durationLabel = formatDurationLabel(point.actualDurationSeconds);
            const progressValue = point.progress || 0;
            return `
              <div class="knowledge-point ${locked ? 'locked' : ''}">
                <div class="point-header">
                  <div class="point-title">${escapeHtml(point.title || '未知标题')}</div>
                  <div class="difficulty-badge difficulty-${difficultyClass}">
                    ${difficultyText}
                  </div>
                </div>
                <div class="point-meta" style="justify-content: space-between;">
                  <span><i class="far fa-clock"></i> 累计投入 ${durationLabel}</span>
                  <span><i class="fas fa-book-open"></i> 已学习 ${progressValue}%</span>
                </div>
                <div class="point-meta" style="justify-content: flex-end;">
                  <span class="status-pill ${statusClass}">${statusLabel}</span>
                </div>
                <p class="point-description">${escapeHtml(point.description || '暂无描述')}</p>
                <button class="${buttonClass}" ${locked ? 'disabled' : ''} onclick="startTraining(${point.id}, ${locked})">
                  <i class="fas fa-play-circle"></i> ${buttonLabel}
                </button>
                ${locked ? `<div class="lock-hint">${point.unlockHint || '完成上一知识点后自动解锁'}</div>` : ''}
              </div>
            `;
        }).join('')}
      </div>
    `;
    }

    /**
     * HTML转义函数，防止XSS攻击
     * @param {string} unsafe - 未转义的字符串
     * @returns {string} 转义后的字符串
     */
    function escapeHtml(unsafe) {
        return unsafe
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    /**
     * 获取难度CSS类名
     * @param {string} difficulty - 难度级别
     * @returns {string} CSS类名
     */
    function getDifficultyClass(difficulty) {
        const difficultyMap = {
            'beginner': 'beginner',
            '初级': 'beginner',
            'intermediate': 'intermediate',
            '中级': 'intermediate',
            'advanced': 'advanced',
            '高级': 'advanced'
        };
        return difficultyMap[difficulty] || 'beginner';
    }

    /**
     * 获取难度显示文本
     * @param {string} difficulty - 难度级别
     * @returns {string} 显示文本
     */
    function getDifficultyText(difficulty) {
        const difficultyMap = {
            'beginner': '初级',
            '初级': '初级',
            'intermediate': '中级',
            '中级': '中级',
            'advanced': '高级',
            '高级': '高级'
        };
        return difficultyMap[difficulty] || '未知';
    }

    /**
     * 开始训练函数
     * @param {number} pointId - 知识点ID
     */
    function startTraining(pointId, locked = false) {
        if (locked) {
            alert('请先完成上一知识点后自动解锁下一项~');
            return;
        }
        console.log('开始学习知识点:', pointId);
        // 修改为正确的URL格式，与后端Controller匹配
        window.location.href = '/knowledge/training/start/' + pointId;
    }

    /**
     * 应用筛选条件
     */
    function applyFilters() {
        const difficulty = document.getElementById('difficultyFilter').value;
        const url = new URL(window.location.href);

        if (difficulty !== '全部难度') {
            url.searchParams.set('difficulty', difficulty);
        } else {
            url.searchParams.delete('difficulty');
        }

        // 重置到第一页
        url.searchParams.set('page', '1');
        window.location.href = url.toString();
    }

    /**
     * 快速跳转到指定页面
     */
    function jumpToPage() {
        const pageInput = document.getElementById('jumpPage');
        const page = parseInt(pageInput.value);
        const totalPages = parseInt(document.getElementById('totalPages').textContent);

        if (page && page >= 1 && page <= totalPages) {
            const url = new URL(window.location.href);
            url.searchParams.set('page', page);
            window.location.href = url.toString();
        } else {
            alert(`请输入有效的页码（1-${totalPages}）`);
            pageInput.focus();
        }
    }
</script>
</body>
</html>